Skip to content

add the sub-offset operator - #2483

Open
mbKaleb wants to merge 1 commit into
zeek:mainfrom
mbKaleb:topic/mbKaleb/gh-2335-sub-end-offset
Open

add the sub-offset operator#2483
mbKaleb wants to merge 1 commit into
zeek:mainfrom
mbKaleb:topic/mbKaleb/gh-2335-sub-end-offset

Conversation

@mbKaleb

@mbKaleb mbKaleb commented Aug 28, 2026

Copy link
Copy Markdown

Fixes #2335

Added

  • sub-offset operator and corresponding documentation.
  • corresponding test-cases under bytes,stream, and operators, matching convention over coverage.

Tested

  • Complete btest suite: 880 passed, 0 failed, 33 skipped
  • New btest coverage: single-offset sub on bytes and stream views with
    boundary cases (0, mid, full length), a const-operand case, and a
    Spicy-syntax assert (tests/hilti/types/bytes/ops.hlt,
    tests/hilti/types/stream/view.hlt, tests/spicy/types/bytes/operators.spicy)

@codspeed-hq

codspeed-hq Bot commented Aug 31, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 43 untouched benchmarks


Comparing mbKaleb:topic/mbKaleb/gh-2335-sub-end-offset (07d8e33) with main (9274feb)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (877b266) during the generation of this report, so 9274feb was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@mbKaleb

mbKaleb commented Sep 1, 2026

Copy link
Copy Markdown
Author

@evantypanski Any thoughts?

@evantypanski

Copy link
Copy Markdown
Member

Hey sorry I haven't gotten to this, I'll get to it either today or tomorrow. I've had some pressing stuff I wanted to get out of the way first :) thanks for your patience!

While waiting, to what extent did you use AI for this PR? Zeek has an AI policy, we don't have it in Spicy yet, but probably should.

@evantypanski evantypanski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core looks right to me, thanks! I had a couple comments on tests because when playing with it, I found it's actually slightly tricky for views. Some tests would help. Feel free to add more edge cases, too.

And my question before will still stand: did you use AI for this PR, and to what extent? Just so we can keep track

constexpr Tag ToUIntBinary = 931;
constexpr Tag Unequal = 932;
constexpr Tag UpperCase = 933;
constexpr Tag SubOffset = 934;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's kind of annoying, but could you move this next to SubOffsets? So this'd be 921, then you bump the number for all the subsequent tags.

That's what we've done eg here: bf92771

constexpr Tag SubOffsets = 3315;
constexpr Tag UnequalBytes = 3316;
constexpr Tag UnequalView = 3317;
constexpr Tag SubOffset = 3318;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as before, can this be 3316 then bump the other 2?

assert y2.sub(y2.find(b"def")[1], end(y2)) == b"de";
assert y.sub(3) == b"012";
assert y.sub(0) == b"";
assert y.sub(|y|) == y;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently lack a test from hilti/spicy for an offset that's too large, mind adding one here? It should clamp. Untested suggestion:

assert y.sub(|y| + 1337) == y;

assert v.sub(3) == b"123";
assert v.sub(0) == b"";
assert v.sub(|v|) == b"123456789";
assert all.sub(5) == b"01234";

@evantypanski evantypanski Sep 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to my comment above on bytes, but views are different, it'd be nice to enshrine that in a test. v.sub(1337) will grow with a cap at 1337 if the underlying stream grows. For example, run this, it'll pass:

module Test {

global stream s = stream(b"abc");
global view<stream> my_view = s;
global view<stream> subbed = my_view.sub(1337);

assert subbed == b"abc";

s += b"def";
assert subbed == b"abcdef";
}

with:

hiltic -j test.hlt

We should test something along those lines. That's tricky behavior, and different from bytes.

EDIT: Oh, and what if the view sub was within range, but then appending puts it out? Like this:

module Test {

import hilti;

global stream s = stream(b"abc");
global view<stream> my_view = s;
global view<stream> subbed = my_view.sub(5);

assert subbed == b"abc";

s += b"a lot more than 5";
assert subbed == b"abca ";
}

Testing this behavior would be nice, since I don't actually know if we have runtime tests for this case. The more the merrier

@mbKaleb

mbKaleb commented Sep 2, 2026

Copy link
Copy Markdown
Author

The core looks right to me, thanks! I had a couple comments on tests because when playing with it, I found it's actually slightly tricky for views. Some tests would help. Feel free to add more edge cases, too.

And my question before will still stand: did you use AI for this PR, and to what extent? Just so we can keep track

  • I used Claude Fable 5.1 to find this issue and explain the codebase+downstream tools.

  • In addition, all written documents and code were reviewed by Fable 5.1 but the language model did not make any final decisions or changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add bytes.sub(end) and stream.sub(end) without an iterator

2 participants